using System;
using Gtk;
using AtDevice;
using Interoperability;

namespace GtkControls
{
    
    
    [System.ComponentModel.Category("GtkControls")]
    [System.ComponentModel.ToolboxItem(true)]
    public partial class PhoneBookWidget : Gtk.Bin
    {
        private NodeStore _items = new NodeStore(typeof(PhoneBookNode));
        private IPhoneBookManager _phonebookInterface;
        private IPhoneBook _currentPhonebook;
        private TextBuffer _buffer;
        
        public PhoneBookWidget()
        {
            this.Build();

            BuildToolsMenu();
            SetColumns();
            SetEnables();
            SetupBuffer();
            
            DeviceHandler.DeviceOpened += delegate {
                OpenDefaultPhonebook();
                FillPhonebookCombobox();
                RefreshList();
            };
            
            phonebookList.NodeSelection.Changed += delegate {
                SetEnables();
                DisplaySelectedItems();                
            };
        }
        
        private void SetupBuffer()
        {
            _buffer = itemView.Buffer;
            TextTag boldTag = new TextTag("bold");
            boldTag.Weight = Pango.Weight.Bold;
            _buffer.TagTable.Add(boldTag);
        }

        private void BuildToolsMenu()
        {
            Gtk.Menu menu = toolsmenu.AppendSubMenu("Tools");
            Gtk.Menu exportMenu = menu.AppendSubMenu("Export");

            // TODO make this dynamic
            exportMenu.AppendMenuItem("Export XML", delegate { ExportPhonebook(new PhonebookXmlExport()); });
            exportMenu.AppendMenuItem("Export vCard", delegate { ExportPhonebook(new PhonebookVcardExport()); });
        }
        
        private void SetColumns()
        {
            phonebookList.AppendColumn("Name", new Gtk.CellRendererText(), "text", 0);
            phonebookList.AppendColumn("Number", new Gtk.CellRendererText(), "text", 1);
            phonebookList.AppendColumn("Office Number", new Gtk.CellRendererText(), "text", 2);
            phonebookList.AppendColumn("Home Number", new Gtk.CellRendererText(), "text", 3);
            phonebookList.AppendColumn("Email", new Gtk.CellRendererText(), "text", 4);
            phonebookList.AppendColumn("Remarks", new Gtk.CellRendererText(), "text", 5);
            phonebookList.NodeStore = _items;
        }

        private void SetEnables()
        {
            if(phonebookList.NodeSelection.SelectedNodes.Length > 0)
            {
                editButton.Sensitive = true;
                deleteButton.Sensitive = true;
                newMessageButton.Sensitive = true;
            }
            else
            {
                editButton.Sensitive = false;
                deleteButton.Sensitive = false;
                newMessageButton.Sensitive = false;
            }
        }

        private void OpenDefaultPhonebook()
        {
            _phonebookInterface = DeviceHandler.Get().GetPhoneBookInterface();
            foreach(var book in _phonebookInterface.GetPhoneBooks())
            {
                _currentPhonebook = book;
                break;
            }
        }

        private void FillPhonebookCombobox()
        {
            int i = 0;
            foreach(var book in _phonebookInterface.GetPhoneBooks())
                phonebookCombobox.InsertText(i++, book.GetName());

            phonebookCombobox.Active = 0;
        }

        private void RefreshList()
        {
            _items.Clear();

            try {
            foreach (var item in _currentPhonebook.GetEntries()) {
                _items.AddNode(new PhoneBookNode(item));
            }
            } catch(AtException)
            {
            }
        }
        
        private void AppendLineToPane(string label, string content)
        {
            TextIter end = _buffer.EndIter;
            _buffer.InsertWithTagsByName(ref end, label + ": ", "bold");
            _buffer.Insert(ref end, content + "\n");
        }
        
        private void ShowInPane(PhoneBookEntry entry)
        {
            AppendLineToPane("Name", entry.Name);
            AppendLineToPane("Mobile number", entry.MobileNumber);
            AppendLineToPane("Office number", entry.OfficeNumber);
            AppendLineToPane("Home number", entry.HomeNumber);
            AppendLineToPane("Email", entry.Email);
            AppendLineToPane("Remarks", entry.Remarks);
        }
        
        private PhoneBookEntry GetSelectedEntry()
        {
            PhoneBookNode entry = (PhoneBookNode)phonebookList.NodeSelection.SelectedNode;
            return entry.Entry;
        }
        
        private void DisplaySelectedItems()
        {
            _buffer.Clear();
            
            if(phonebookList.NodeSelection.SelectedNodes.Length > 0)
            {
                ShowInPane(GetSelectedEntry());
            }
        }

        protected virtual void OnNewButtonClicked (object sender, System.EventArgs e)
        {
            PhoneBookNewEntryWindow wnd = new PhoneBookNewEntryWindow(_currentPhonebook);
            wnd.Destroyed += delegate {
                RefreshList();
            };
            wnd.Show();
        }

        protected virtual void OnDeleteButtonClicked (object sender, System.EventArgs e)
        {
            _currentPhonebook.DeleteEntry(GetSelectedEntry());
            RefreshList();
        }

        protected virtual void OnNewMessageButtonClicked (object sender, System.EventArgs e)
        {
            PhoneBookEntry entry = GetSelectedEntry();
            new TextMessageNewWindow(entry.MobileNumber, "").Show();
        }

        protected virtual void OnEditButtonClicked (object sender, System.EventArgs e)
        {
            PhoneBookEntry entry = GetSelectedEntry();
            PhoneBookEditEntryWindow wnd = new PhoneBookEditEntryWindow(entry, _currentPhonebook);
            wnd.Destroyed += delegate {
                RefreshList();
            };
            wnd.Show();
        }

        protected virtual void OnPhonebookComboboxChanged (object sender, System.EventArgs e)
        {
            int selected = phonebookCombobox.Active;
            _currentPhonebook = _phonebookInterface.GetPhoneBooks()[selected];
            RefreshList();
        }

        private void ExportPhonebook (IPhonebookExport exporter)
        {
            Gtk.FileChooserDialog dlg = new Gtk.FileChooserDialog("Export phonebook to file",
                                                                  null, FileChooserAction.Save,
                                                                  "Cancel", ResponseType.Cancel,
                                                                  "Export", ResponseType.Accept);
            //dlg.Filename = String.Format("list{0}", exporter.GetFileSuffix());
            dlg.CurrentName = String.Format("list{0}", exporter.GetFileSuffix());
            dlg.Filter = new FileFilter();
            dlg.Filter.AddPattern(exporter.GetFileSuffix());

            ResponseType response = (ResponseType)dlg.Run();
            dlg.Hide();
            if(response == ResponseType.Accept)
            {
                exporter.ExportPhonebook(_currentPhonebook, dlg.Filename);
                MessageDialog md = new MessageDialog(null,
                                          DialogFlags.DestroyWithParent,
                                          MessageType.Info,
                                          ButtonsType.Close,
                                          "Phonebook successfully exported to " + dlg.Filename);
              md.Run();
              md.Destroy();
            }
            dlg.Destroy();
        }
    }
}
